package com.iot.geteway.filters;

import com.dc3.common.constant.ServiceConstant;
import com.iot.openfeign.UserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;

/**
 * @Author 咕唧
 * @Date 2022/7/19 20:15
 * @Version 1.0
 */
@Component
public class AuthenGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthenGatewayFilterFactory.Config> {

    private AuthenFilter authenFilter;

    @Autowired
    public void setAuthenFilter(AuthenFilter authenFilter) {
        this.authenFilter = authenFilter;
    }

    @Override
    public GatewayFilter apply(Config config) {
        return authenFilter;
    }

    public static class Config {

    }

    @Component
    static class AuthenFilter implements GatewayFilter, Ordered {

        private UserClient userClient;

        @Resource
        public void setUserClient(UserClient userClient) {
            this.userClient = userClient;
        }

        /**
         * 对用户令牌进行过滤 ，约定令牌通过请求头传递
         *
         * @param exchange
         * @param chain
         * @return
         */
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            String jwtToken = exchange.getRequest().getHeaders().getFirst(ServiceConstant.Header.X_AUTH_TOKEN);

            //请求检查令牌的服务,对令牌进行检查,然后再决定如何处理
            return Mono.just(jwtToken == null ? "" : jwtToken)
                    .flatMap(s -> userClient.checkToken(s))
                    .flatMap(r -> {
                        if (((Integer) r.getData()) != 0) {
                            return chain.filter(exchange);
                        } else {
                            return exchange.getResponse()
                                    .writeAndFlushWith(Mono.just(Mono.just(DefaultDataBufferFactory
                                            .sharedInstance
                                            .allocateBuffer()
                                            .write("尚未登录，请登录".getBytes(StandardCharsets.UTF_8)))));
                        }
                    });
        }

        /**
         * 过滤器的优先级
         *
         * @return
         */
        @Override
        public int getOrder() {
            return 0;
        }
    }
}
